package dbAccess;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Date;
import java.sql.*;
public class Patient 
{
	private final static String defaultStr = "unknown";
	private int patientId;
	private int SIN;
	private String FirstName;
	private String LastName;
	private String EmailAddress;
	private String PhoneNum;
	private String HomeAddress;
	private String password;
	private java.sql.Date DateOfBirth;
	private String gender;
	private String HealthCardNum;
	private String CurrentHealth;
	private int DefaultDoc;
	
	private String statusMsg;
	private String creator;
	
	public Patient(String creatorIn)
	{
		patientId = -1;
		SIN = -1;
		FirstName = defaultStr;
		LastName = defaultStr;
		EmailAddress = defaultStr;
		PhoneNum = defaultStr;
		password = defaultStr;
		DateOfBirth = java.sql.Date.valueOf("0000-00-00");
		gender = defaultStr;
		HealthCardNum = defaultStr;
		CurrentHealth = "Waiting for doctor input.";
		DefaultDoc = -1;
		statusMsg = "";
		creator = creatorIn;
	}
	
	//creates a new patient or updates existing one
	public Boolean registerPatient(String action)
	{
		if(action.equals("update"))
		{
			int patientId = this.getPatientId();
			String updateQuery = "update tbl_patient set IsDeleted = '1' where PatientId = " + patientId ;
			DbAccess access = new DbAccess();
			access.ExecuteUpdate(access.connect(), updateQuery);
			Login.Log(creator, updateQuery);
		}
		
		this.setStatusMsg("");
		//check if SIN or email address already exists in tbl_person
		DbAccess access = new DbAccess();
		String query = "select SIN, EmailAddress from tbl_patient where (SIN = " + SIN + " or EmailAddress = '" + EmailAddress + "'";
		query += ") and IsDeleted = '0' ";
		
		try 
		{
		ResultSet rs = access.ExecuteSelect(access.connect(), query);
		if (rs.next())
		{
			this.setStatusMsg("Patient already exists.");
			return false;
		}
		}
		catch (SQLException e)
		{
			this.setStatusMsg("Duplication check error occurred: " + e.getMessage());
			return false;
		}
			
		//insert into tbl_patient
		query = "insert into tbl_patient ";
		query += "(EmailAddress, SIN, FirstName, LastName, Gender, DateOfBirth, Phone, HomeAddress, ";
		query += "DocId, HealthCard, CurrentHealth, Password, IsDeleted) ";
		query += "values ('" + EmailAddress + "'," + SIN + ",'" + FirstName + "','" + LastName + "','" + gender + "','" + DateOfBirth + "','" + PhoneNum;
		query += "','" + HomeAddress + "'," + DefaultDoc + ",'" + HealthCardNum  + "','" + CurrentHealth + "','" + password + "',0)";
		
		if (!(access.ExecuteUpdate(access.connect(), query)))
		{
			this.setStatusMsg("Could not update tbl_patient with patient information.");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		int oldPatientId = this.getPatientId();
		//store patient ID field
		if (!(evalPatientId()))
		{
			return false;
		}
		
		if(action.equals("update"))
		{
			//must update other references to old patient id in tbl_appointment, tbl_doc/staff_patient_access
			int patientId = this.getPatientId();
			String updateApptQuery = "update tbl_appointment set tbl_appointment.PatientId = " + patientId + " where " ;
			updateApptQuery += "tbl_appointment.PatientId = " + oldPatientId;
			
			String updateDocAccessQuery = "update tbl_doc_patient_access set tbl_doc_patient_access.PatientId = " + patientId + " where " ;
			updateDocAccessQuery += "tbl_doc_patient_access.PatientId = " + oldPatientId;
			
			String updateStaffAccessQuery = "update tbl_staff_patient_access set tbl_staff_patient_access.PatientId = " + patientId + " where " ;
			updateStaffAccessQuery += "tbl_staff_patient_access.PatientId = " + oldPatientId;
		
			DbAccess access2 = new DbAccess();
			
			access2.ExecuteUpdate(access2.connect(), updateApptQuery);
			Login.Log(creator, updateApptQuery);
			
			access2.ExecuteUpdate(access2.connect(), updateDocAccessQuery);
			Login.Log(creator, updateDocAccessQuery);
			
			access2.ExecuteUpdate(access2.connect(), updateStaffAccessQuery);
			Login.Log(creator, updateStaffAccessQuery);
			
			this.setStatusMsg(this.getFirstName() + " " + this.getLastName() + " updated with new ID: " + this.getPatientId());
			return true;
		}
		this.setStatusMsg("New patient created with ID: " + this.getPatientId());
		return true;
	}
	
	private Boolean evalPatientId()
	{
		DbAccess access = new DbAccess();
		String query = "select tbl_patient.PatientId from tbl_patient where tbl_patient.SIN = " + this.SIN + " and ";
		query += "tbl_patient.IsDeleted = 0";
		
		try
		{
			ResultSet rs = access.ExecuteSelect(access.connect(), query);
			rs.next();
			this.patientId = rs.getInt("tbl_patient.PatientId");
			return true;
		}
		catch (SQLException e)
		{
			return false;
		}	
	}
	
	public Boolean removePatient(int PatientId)
	{
		DbAccess access = new DbAccess();
		
		//remove access
		String query = "DELETE FROM tbl_doc_patient_access WHERE PatientId='" + PatientId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update doc/patient access records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		query = "DELETE FROM tbl_staff_patient_access WHERE PatientId='" + PatientId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update staff/patient access records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		//set isDeleted for tbl_patient=1
		query = "UPDATE tbl_patient SET IsDeleted=1 WHERE PatientId='" + PatientId + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update staff/patient access records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		//delete appointments set in the future
		Date now = new Date();
		Calendar calendar = Calendar.getInstance();
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-mm-dd");
		query = "DELETE FROM tbl_appointment WHERE PatientId='" + PatientId + "' AND Date > '" + dateFormat.format(calendar.getTime()) + "'";
		if(!access.ExecuteUpdate(access.connect(), query))
		{
			this.setStatusMsg("failed to update appointment records");
			return false;
		}
		else
		{
			Login.Log(creator, query);
		}
		
		this.setStatusMsg("Patient has been successfully deleted.");
		return true;
	}


	public int getPatientId() {
		return patientId;
	}

	public void setPatientId(int patientID) {
		this.patientId = patientID;
	}

	public int getSIN() {
		return SIN;
	}

	public void setSIN(int sin) {
		SIN = sin;
	}

	public String getFirstName() {
		return FirstName;
	}

	public void setFirstName(String firstName) {
		FirstName = firstName;
	}

	public String getLastName() {
		return LastName;
	}

	public void setLastName(String lastName) {
		LastName = lastName;
	}

	public String getEmailAddress() {
		return EmailAddress;
	}

	public void setEmailAddress(String emailAddress) {
		EmailAddress = emailAddress;
	}

	public String getPhoneNum() {
		return PhoneNum;
	}

	public void setPhoneNum(String phoneNum) {
		PhoneNum = phoneNum;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public java.sql.Date getDateOfBirth() {
		return DateOfBirth;
	}

	public void setDateOfBirth(java.sql.Date DateOfBirth) {
		this.DateOfBirth = DateOfBirth;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getHealthCardNum() {
		return HealthCardNum;
	}

	public void setHealthCardNum(String healthCardNum) {
		HealthCardNum = healthCardNum;
	}

	public String getCurrentHealth() {
		return CurrentHealth;
	}

	public void setCurrentHealth(String currentHealth) {
		CurrentHealth = currentHealth;
	}

	public int getDefaultDoc() {
		return DefaultDoc;
	}

	public void setDefaultDoc(int defaultDoc) {
		DefaultDoc = defaultDoc;
	}

	public String getStatusMsg() {
		return statusMsg;
	}

	public void setStatusMsg(String errorMsg) {
		this.statusMsg = errorMsg;
	}

	public String getHomeAddress() {
		return HomeAddress;
	}

	public void setHomeAddress(String homeAddress) {
		HomeAddress = homeAddress;
	}

}
